#include "head.h"



//获得md5码
int getMd5(char *fileName, char *s){
    int fd = open(fileName, O_RDWR);
    ERROR_CHECK(fd, -1, "open");
    struct stat statbuf;
    int ret = fstat(fd,&statbuf);
    ERROR_CHECK(ret,-1,"fstat");
    char *p = (char *)mmap(NULL, statbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    ERROR_CHECK(p, MAP_FAILED, "mmap");
    unsigned char MD[16];
    MD5((unsigned char *)p, strlen(p), MD);
    //char md5[50] = {0};
    for (int i = 0; i < 16; ++i) {
        //printf("%x", MD[i]);
        sprintf(s+i*2, "%02x", MD[i]);
        //strcat(s, md5);
    }
    puts(s);
    close(fd);
    return 0;
}


int sqlSplice(char *sql, virDir_t *curVd){
    strcat(sql, curVd->name);
    strcat(sql, "',");
    //把整形数据转换成字符串在进行拼接
    // char itostr[20] = {0};
    // sprintf(itostr, "%d", curVd->pre_id);
    strcat(sql, curVd->pre_id);
    strcat(sql, ",'");
    strcat(sql, curVd->md5);
    strcat(sql, "','");
    strcat(sql, curVd->user);
    strcat(sql, "','");
    strcat(sql, curVd->isDelete);
    strcat(sql, "','");
    strcat(sql, curVd->type);
    strcat(sql, "')");
    return 0;
}

//获取当前工作“目录”下虚拟文件表信息
int getVirDirInfo(virDir_t *vd, char *userName){
    MYSQL *db = mysql_init(NULL);
    databaseInit(db);

    char sql[1024] = "select * from directory where user = '";
    strcat(sql, userName);
    strcat(sql, "' and pre_id = 0");

    int qret = mysql_query(db, sql);
    SQL_ERROR_CHECK(db, qret, 0);
    MYSQL_RES *result = mysql_store_result(db);
    printf("The row number is %lld\n", mysql_num_rows(result));
    //有相同用户则找到一行结果，否则未找到！
    MYSQL_ROW row;
    char dirInfo[1024] = {0};
    while ((row = mysql_fetch_row(result))!= NULL) {
        for (int j = 0; j < mysql_num_fields(result); ++j) {
            strcat(dirInfo, row[j]);
            strcat(dirInfo, " ");
        }
    }
    mysql_free_result(result);
    mysql_close(db);
    strcpy(vd->id, strtok(dirInfo, " "));
    strcpy(vd->name, strtok(NULL, " "));
    strcpy(vd->pre_id, strtok(NULL, " "));
    strcpy(vd->md5, strtok(NULL, " "));
    strcpy(vd->user, strtok(NULL, " "));
    strcpy(vd->isDelete, strtok(NULL, " "));
    strcpy(vd->type, strtok(NULL, " "));
    return 0;
}

//在固定文件夹下创建虚拟目录
int  myMkdir(task_t* pTask, virDir_t *preVd)//创建新目录
{
    char *orderName = strtok(pTask->buf, " ");//命令，cond中内容应为mkdir
    char *dirName = strtok(NULL, " ");

    MYSQL *db = mysql_init(NULL);
    databaseInit(db);
    //先默认用户登录时已在自身用户所在“目录”下
    virDir_t *curVd = (virDir_t *)calloc(1, sizeof(virDir_t));
    puts(dirName);
    //先判断物理目录下是否有该目录，如果有，直接在虚拟文件表加一行，如果没有，则创建
    DIR *pdir1 = opendir("/home/hcr/hcrprog_2/Filehome");
    int flag = 0;
    struct dirent *p;
    while ((p = readdir(pdir1)) != NULL)
    {
        if (!strcmp(p->d_name, dirName)) {
            //目录已存在
            flag = 1;
            break;
        }
    }
    if (flag == 0) {
        int fd = open(dirName, O_RDWR | O_CREAT, 0666);
        ERROR_CHECK(fd, -1, "open");
        // MD5为主键，不允许重复，所以应该使其不为空
        close(fd);
        char writePath[1024] = {0};
        myPwd(writePath, preVd);
        FILE *fp = fopen(dirName, "a+");
        fwrite(writePath, strlen(writePath), 1, fp);
        fwrite(" 's ", 4, 1, fp);
        fwrite(dirName, strlen(dirName), 1, fp);
        fclose(fp);
    }

    strcpy(curVd->name, dirName);
    strcpy(curVd->pre_id, preVd->id);
    //curVd->pre_id = preVd->id;
    char md5[1024] = {0};
    getMd5(dirName, md5);
    strcpy(curVd->md5, md5);
    strcpy(curVd->user, preVd->user);
    strcpy(curVd->isDelete, "N");
    strcpy(curVd->type, "d");

    char sql1[1024] = "select * from directory where pre_id = ";
    strcat(sql1, preVd->id);
    strcat(sql1, " and name = '");
    strcat(sql1, dirName);
    strcat(sql1, "'");
    int qret = mysql_query(db, sql1);
    SQL_ERROR_CHECK(db, qret, 0);
    MYSQL_RES *result = mysql_store_result(db);
    if(mysql_num_rows(result) == 0) {
        char sql[1024] = "insert into directory (name,pre_id,md5,user,isDelete,type) values('";
        sqlSplice(sql, curVd);
        qret = mysql_query(db, sql);
        SQL_ERROR_CHECK(db, qret, 0);
    }
    else {
        send(pTask->netFd, "Directory has existed!", 22, 0);
    }
    mysql_close(db);
    return 0;
}

int myPwd(char *returnPath, virDir_t *preVd){ //打印当前目录
    MYSQL *db = mysql_init(NULL);
    databaseInit(db);
    //防止当前结构体被修改
    virDir_t *curVd = (virDir_t*)calloc(1, sizeof(virDir_t));
    strcpy(curVd->id, preVd->id);
    strcpy(curVd->name, preVd->name);
    strcpy(curVd->pre_id, preVd->pre_id);
    strcpy(curVd->md5, preVd->md5);
    strcpy(curVd->user, preVd->user);
    strcpy(curVd->isDelete, preVd->isDelete);
    strcpy(curVd->type, preVd->type);
    //printf("id = %s, pre_ id = %s\n", curVd->id, curVd->pre_id);
    char front[1024] = {0};
    char back[1024] = {0};
    strcpy(back, curVd->name);
    strcat(back, "/");

    while (atoi(curVd->pre_id) != 0) {
        
        char sql[300] = "select name,pre_id from directory where id = '";
        strcat(sql, curVd->pre_id);
        strcat(sql, "'");
        int qret = mysql_query(db, sql);
        SQL_ERROR_CHECK(db, qret, 0);
        MYSQL_RES *result = mysql_store_result(db);
        printf("The row number is %lld\n", mysql_num_rows(result));
        MYSQL_ROW row;
        char dirInfo[1024] = {0};
        while ((row = mysql_fetch_row(result))!= NULL) {
            for (int j = 0; j < mysql_num_fields(result); ++j) {
                strcat(dirInfo, row[j]);
                strcat(dirInfo, " ");
            }
        }
        
        strcpy(curVd->id, curVd->pre_id);
        strcpy(curVd->name, strtok(dirInfo, " "));
        strcpy(curVd->pre_id, strtok(NULL, " "));
        strcpy(front, curVd->name);
        strcat(front, "/");
        strcat(front, back);
        strcpy(back, front);
        mysql_free_result(result);
        mysql_close(db);
    }
    strcpy(front, "Filehome/");
    strcat(front, back);
    //puts(front);
    //printf("pwd切后id = %s, pre_ id = %s\n", preVd->id, preVd->pre_id);
    strcpy(returnPath, front);
    //send(pTask->netFd,front,strlen(front),0);
}

int removeFile(task_t *pTask, virDir_t *preVd){//删除目标文件
    MYSQL *db = mysql_init(NULL);
    databaseInit(db);

    char str[1024] = {0};
    strcpy(str, pTask->buf);
    char *w = strtok(str, " ");
    char a[512] = {0};
    char b[512] = {0};
    strcpy(a, w);
    if ((w = strtok(NULL, " ")) != NULL) {
        strcpy(b, w);
    }

    char sql[300] = "update directory set isDelete = 'Y' where pre_id = '";
    strcat(sql, preVd->id);
    strcat(sql, "' and name = '");
    strcat(sql, b);
    strcat(sql, "' and isDelete = 'N'");
    int qret = mysql_query(db, sql);
    SQL_ERROR_CHECK(db, qret, 0);
    mysql_close(db);
    return 0;
}

int cd(task_t *pTask, virDir_t *preVd) {
    MYSQL *db = mysql_init(NULL);
    databaseInit(db);

    char str[1024] = {0};
    strcpy(str, pTask->buf);
    char *w = strtok(str, " ");
    char a[512] = {0};
    char b[512] = {0};
    strcpy(a, w);
    if ((w = strtok(NULL, " ")) != NULL) {
        strcpy(b, w);
    }
    //分割路径
    char *words[20];
    char *s = strtok(b, "/");
    int i = 0;
    words[i] = s;
    //int i = 1;
    while ((s = strtok(NULL, "/"))!= NULL) {
        words[++i] = s;
    }
    for (int j = 0; j <= i; j++) {
        puts(words[j]);
    }
    
    int flag = 0;
    char strTemp[1024] = {0};
    if (!strncmp(words[0], "Filehome", 8)) {
        printf("hhh\n");
        if (i < 1) {
            send(pTask->netFd, "No such directory!", 18, 0);
            return -1;
        }
        else if (!strncmp(words[1], preVd->user, strlen(preVd->user))) {
            //cd Firehome/hcr/
            printf("hhhhdf\n");
            getVirDirInfo(preVd, preVd->user);
            printf("id = %s\n", preVd->id);
            flag = 1;
        }
        else {
            send(pTask->netFd, "No such directory!", 18, 0);
            return -1;
        }
    }
    char dirInfo[1024] = {0};
    for (int j = 0; j <= i; ++j) {
        printf("fgfhdd\n");
        if (flag == 1 && j < 2) {
            continue;
        }
        char sql[300] = "select * from directory where pre_id = '";
        strcat(sql, preVd->id);
        strcat(sql, "' and name = '");
        strcat(sql, words[j]);
        strcat(sql, "' and type = '");
        strcat(sql, "d'");
        int qret = mysql_query(db, sql);
        SQL_ERROR_CHECK(db, qret, 0);
        MYSQL_RES *result = mysql_store_result(db);
        printf("The row number is %lld\n", mysql_num_rows(result));
        if (mysql_num_rows(result) == 0) {
            send(pTask->netFd,"No such directory!",18,0);
            return -1;
        }
        bzero(dirInfo, sizeof(dirInfo));
        MYSQL_ROW row;
        while ((row = mysql_fetch_row(result))!= NULL) {
            for (int j = 0; j < mysql_num_fields(result); ++j) {
                strcat(dirInfo, row[j]);
                strcat(dirInfo, " ");
            }
        }
        
        strcpy(preVd->id, strtok(dirInfo, " "));
        strcpy(preVd->name, strtok(NULL, " "));
        strcpy(preVd->pre_id, strtok(NULL, " "));
        strcpy(preVd->md5, strtok(NULL, " "));
        strcpy(preVd->user, strtok(NULL, " "));
        strcpy(preVd->isDelete, strtok(NULL, " "));
        strcpy(preVd->type, strtok(NULL, " "));
        strcat(strTemp, preVd->name);
        strcat(strTemp, "/");
        mysql_free_result(result);
        mysql_close(db);
    }
    //printf("cd中: id = %s, preid = %s\n", preVd->id, preVd->pre_id);
    //移至目标路径，直接pwd即可
    char cdPath[1024] = {0};
    myPwd(cdPath, preVd);
    //printf("pwd后: id = %s, preid = %s\n", preVd->id, preVd->pre_id);
    puts(cdPath);
    send(pTask->netFd, cdPath, strlen(cdPath), 0);
}

int ls(task_t *pTask, virDir_t *preVd) {
    MYSQL *db = mysql_init(NULL);
    databaseInit(db);

    char str[1024] = {0};
    strcpy(str, pTask->buf);
    char *w = strtok(str, " ");
    char a[512] = {0};
    char b[512] = {0};
    strcpy(a, w);
    if ((w = strtok(NULL, " ")) != NULL) {
        strcpy(b, w);
    }

    if (strlen(b) == 0) {
        char sql[1024] = "select name from directory where pre_id = ";
        strcat(sql, preVd->id);
        strcat(sql, " and isDelete = 'N'");
        int qret = mysql_query(db, sql);
        SQL_ERROR_CHECK(db, qret, 0);
        MYSQL_RES *result = mysql_store_result(db);
        printf("The row number is %lld\n", mysql_num_rows(result));

        MYSQL_ROW row;
        char dirInfo[1024] = {0};
        while ((row = mysql_fetch_row(result)) != NULL){
            for (int j = 0; j < mysql_num_fields(result); ++j){
                printf("%s  ", row[j]);
                strcat(dirInfo, row[j]);
                strcat(dirInfo, " ");
            }
        }
        mysql_free_result(result);
        mysql_close(db);
        printf("\n");
        send(pTask->netFd, dirInfo, strlen(dirInfo), 0);
        return 0;
    }

    //分割路径
    char *words[20];
    char *s = strtok(b, "/");
    int i = 0;
    words[i] = s;
    while ((s = strtok(NULL, "/"))!= NULL) {
        words[++i] = s;
    }
    for (int j = 0; j <= i; j++) {
        puts(words[j]);
    }
    
    int flag = 0;
    char strTemp[1024] = {0};
    if (!strncmp(words[0], "Filehome", 8)) {
        printf("hhh\n");
        if (i < 1) {
            send(pTask->netFd, "No permission!", 14, 0);
            return -1;
        }
        else if (!strncmp(words[1], preVd->user, strlen(preVd->user))) {
            //cd Firehome/hcr/
            printf("hhhhdf\n");
            getVirDirInfo(preVd, preVd->user);
            printf("id = %s\n", preVd->id);
            flag = 1;
        }
        else {
            send(pTask->netFd, "No such directory!", 18, 0);
            return -1;
        }
    }
    for (int j = 0; j <= i; ++j) {
        printf("fgfhdd\n");
        if (flag == 1 && j < 2) {
            continue;
        }
        char sql[300] = "select * from directory where pre_id = '";
        strcat(sql, preVd->id);
        strcat(sql, "' and name = '");
        strcat(sql, words[j]);
        strcat(sql, "' and type = '");
        strcat(sql, "d'");
        int qret = mysql_query(db, sql);
        SQL_ERROR_CHECK(db, qret, 0);
        MYSQL_RES *result = mysql_store_result(db);
        printf("The row number is %lld\n", mysql_num_rows(result));
        if (mysql_num_rows(result) == 0) {
            send(pTask->netFd,"No such directory!",18,0);
            return -1;
        }

        MYSQL_ROW row;
        char dirInfo[1024] = {0};
        while ((row = mysql_fetch_row(result))!= NULL) {
            for (int j = 0; j < mysql_num_fields(result); ++j) {
                strcat(dirInfo, row[j]);
                strcat(dirInfo, " ");
            }
        }
        mysql_free_result(result);
        mysql_close(db);
        strcpy(preVd->id, strtok(dirInfo, " "));
        strcpy(preVd->name, strtok(NULL, " "));
        strcpy(preVd->pre_id, strtok(NULL, " "));
        strcpy(preVd->md5, strtok(NULL, " "));
        strcpy(preVd->user, strtok(NULL, " "));
        strcpy(preVd->isDelete, strtok(NULL, " "));
        strcpy(preVd->type, strtok(NULL, " "));
        strcat(strTemp, preVd->name);
        strcat(strTemp, "/");
    }
    //找到目标路径的id
    char sql[1024] = "select name from directory where pre_id = ";
    strcat(sql, preVd->id);
    strcat(sql, " and isDelete = 'N'");
    int qret = mysql_query(db, sql);
    SQL_ERROR_CHECK(db, qret, 0);
    MYSQL_RES *result = mysql_store_result(db);
    printf("The row number is %lld\n", mysql_num_rows(result));
    MYSQL_ROW row;
    char dirInfo[1024] = {0};
    while ((row = mysql_fetch_row(result)) != NULL)
    {
        for (int j = 0; j < mysql_num_fields(result); ++j)
        {
            printf("%s  ", row[j]);
            strcat(dirInfo, row[j]);
            strcat(dirInfo, " ");
        }
    }
    mysql_free_result(result);
    mysql_close(db);
    printf("\n");
    send(pTask->netFd, dirInfo, strlen(dirInfo), 0);
    return 0;
}
